<?php

class Cache {

    private $obj = null;
    private $args = null;
    private $cacheExpire = 5;

    public function __input( $obj, $args ) {
        $this->obj = $obj;
        $this->args = $args;
        if ( @$this->obj->setting[ 'cache_time' ] ) {
            $this->cacheExpire = $this->obj->setting[ 'cache_time' ];
        }
        return $this;
    }

    private function getFile( $id ) {
        mkdirs( APP_CACHE );
        return APP_CACHE . md6( $id ) . ".php";
    }

    private function Access( $method = 'get', $cacheFile, $value = null ) {
        if ( $method == 'set' ) {
            if ( file_exists( $cacheFile ) ) $this->Access( 'del', $cacheFile );
            $cacheValue = "<?php die();?>" . ( $this->cacheExpire * 3600 + time() ) . serialize( $value );
            file_put_contents( $cacheFile, $cacheValue );
            chmod( $cacheFile, 0666 );
            return $value;
        }

        if ( $method == 'get' ) {
            if ( !file_exists( $cacheFile ) ) {
                return false;
            }
            $value = file_get_contents( $cacheFile );
            if ( substr( $value, 14, 10 ) < time() ) {
                $this->Access( 'del', $cacheFile );
                return false;
            }
            return unserialize( substr( $value, 24 ) );
        }

        if ( $method == 'del' ) {
            return @unlink( $cacheFile );
        }
    }

    public function update( $name = null ) {
        if ( $name == null ) {
            $cacheMethods = get_class_methods( $this );
            foreach ( $cacheMethods as $method ) {
                if ( preg_match( '/^yl_/', $method ) ) {
                    call_user_func( array( $this, $method ) );
                }
            }
            return true;
        }
        if ( is_string( $name ) ) {
            if ( method_exists( $this, 'yl_' . $name ) ) {
                return call_user_func( array( $this, 'yl_' . $name ) );
            }
        }
        if ( is_array( $name ) ) {
            foreach ( $name as $v ) {
                if ( method_exists( $this, 'yl_' . $v ) ) {
                    call_user_func( array( $this, 'yl_' . $v ) );
                }
            }
            return true;
        }
        return false;
    }

    private function write( $t, $conditions = null, $sort = null, $fields = null, $file = null ) {
        $this->obj->table = $t;
        $result = $this->obj->findAll( $conditions, $sort, $fields );
        $tmp = array();
        foreach ( $result as $v ) {
            $tmp[ $v[ 'id' ] ] = $v;
        }
        unset( $result );
        $this->Access( 'set', $this->getFile( $file != null ? $file : $t ), $tmp );
        return $tmp;
    }

    private function yl_setting() {
        $this->obj->table = "setting";
        $result = $this->obj->findAll();
        $tmp = array();
        foreach ( $result as $v ) {
            $tmp[ $v[ 'id' ] ] = $v[ 'val' ];
        }

        if ( !empty( $tmp[ 'cache_time' ] ) && intval( $tmp[ 'cache_time' ] ) > 0 ) {
            $this->cacheExpire = $tmp[ 'cache_time' ];
        }
        unset( $result );
        $this->Access( 'set', $this->getFile( $this->obj->table ), $tmp );
        return $tmp;
    }

    private function yl_page() {
        return $this->write( "article", array( 'model' => 'page' ), null, 'id,sid,uid,title,alias,model,oid,dateline', 'page' );
    }

    private function yl_tag() {
        return $this->write( 'tag', null, 'total desc', 'id,tag,total' );
    }

    private function yl_sort() {
        $this->obj->table = "sort";
        $result = $this->obj->findAll( null, 'oid asc, id desc' );
        $tmp = array();
        foreach ( $result as $v ) {
            $tmp[ $v[ 'model' ] ][ $v[ 'id' ] ] = $v;
        }
        unset( $result );
        $this->Access( 'set', $this->getFile( $this->obj->table ), $tmp );
        return $tmp;
    }

    private function yl_link() {
        return $this->write( "link" );
    }

    private function yl_plugin() {
        return $this->write( 'plugin' );
    }

    private function yl_user() {
        return $this->write( 'user' );
    }

    public function get( $id ) {
        if ( $this->{'cache_' . $id} != null ) {
            return $this->{'cache_' . $id};
        }
        if ( !$data = $this->Access( 'get', $this->getFile( $id ) ) ) {
            $method = "yl_" . $id;
            $data = $this->$method();
        }
        $this->{'cache_' . $id} = $data;
        return $this->{'cache_' . $id};
    }
}